﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace MPev
{
    public partial class MainForm : Form
    {
        string MPevVersion = "0.5";
        string currentFilename;

        MPModel model;
        
        public MainForm()
        {
            InitializeComponent();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Are you sure?", "Exit MPev " + MPevVersion, MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
                Close();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("MPev is a editor/visualizer for Materialization Pattern(MP) models.", "About MPev " + MPevVersion);
        }

        private void classDiagramToolStripMenuItem_Click(object sender, EventArgs e)
        {
            StreamWriter outfile = new StreamWriter("temp.dot", false, Encoding.Default);

            // header
            outfile.WriteLine("digraph G {");
            outfile.WriteLine("node[fontname=\"Arial\" fontsize=20 shape=\"record\"]");
            outfile.WriteLine("edge[arrowsize=2.0 fontname=\"Arial\" fontsize=16 minlen=2]");
            outfile.WriteLine();

            // body
            outfile.WriteLine(model.toString4Dot());
           
            // tailer
            outfile.WriteLine();
            outfile.WriteLine("}");

            outfile.Close();

            // execute dotty
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            string command = "dotty";
            string args = "temp.dot";
            process.EnableRaisingEvents = false;
            process.StartInfo.FileName = command;
            process.StartInfo.Arguments = args;
            process.Start();
        }

        private void graphToolStripMenuItem_Click(object sender, EventArgs e)
        {
            StreamWriter sw = new StreamWriter("temp.dot", false, Encoding.Default);

            // header
            sw.WriteLine("digraph G {");
            sw.WriteLine("node[fontname=\"Arial\" fontsize=20]");
            sw.WriteLine("edge[arrowsize=2.0 fontname=\"Arial\" fontsize=16 minlen=2]");
            sw.WriteLine();

            // body
            sw.WriteLine(model.graphConversion());
            
            // tailer
            sw.WriteLine();
            sw.WriteLine("}");

            sw.Close();

            System.Diagnostics.Process process = new System.Diagnostics.Process();
            string command = "dotty";
            string args = "temp.dot";
            process.EnableRaisingEvents = false;
            process.StartInfo.FileName = command;
            process.StartInfo.Arguments = args;
            process.Start();
        }

        private void newModel()
        {
            model = new MPModel();

            mpGroupControl1.group = model.NounPart[0];
            mpGroupControl2.group = model.NounPart[1];
            mpGroupControl3.group = model.NounPart[2];
            mpGroupControl4.group = model.NounPart[3];

            mpGroupControl5.group = model.VerbPart[0];
            mpGroupControl6.group = model.VerbPart[1];
            mpGroupControl7.group = model.VerbPart[2];

            mpRelControl1.rel = model.NounRel[0];
            mpRelControl2.rel = model.NounRel[1];
            mpRelControl3.rel = model.NounRel[2];

            mpRelControl4.rel = model.VerbRel[0];
            mpRelControl5.rel = model.VerbRel[1];
        }


        private void MainForm_Load(object sender, EventArgs e)
        {
            newModel();
            updateCurrentFilename("Noname");
            syncModel2Screen();

            saveFileDialog.Filter = "MP Models (*.mpm)|*.mpm|" + "All Files|";
            openFileDialog.Filter = "MP Models (*.mpm)|*.mpm|" + "All Files|";
        }

        private void saveFile()
        {
            StreamWriter sw = new StreamWriter(currentFilename, false, Encoding.Default);
            model.Save(sw);
            sw.Close();
        }

        private void saveAs()
        {
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                updateCurrentFilename(saveFileDialog.FileName);
                saveFile();
            }
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (currentFilename == "Noname") saveAs();
            else saveFile();
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                StreamReader sr = new StreamReader(openFileDialog.FileName, Encoding.Default);
                model.Load(sr);
                sr.Close();
                updateCurrentFilename(openFileDialog.FileName);
                syncModel2Screen();
            }
        }

        private void syncModel2Screen()
        {
            textBox1.Text = model.statement;
            comboBox.Text = model.type;
            checkBox.Checked = model.existVerbModifier;
            updateInstructionText();

            mpGroupControl1.syncListBox();
            mpGroupControl2.syncListBox();
            mpGroupControl3.syncListBox();
            mpGroupControl4.syncListBox();
            mpGroupControl5.syncListBox();
            mpGroupControl6.syncListBox();
            mpGroupControl7.syncListBox();

            mpRelControl1.syncText();
            mpRelControl2.syncText();
            mpRelControl3.syncText();
            mpRelControl4.syncText();
            mpRelControl5.syncText();
        }

        private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            model.type = comboBox.Text;
            updateInstructionText();

            MPClassType type1, type2;
            if (model.type == "8" || model.type == "8A")
            {
                type1 = MPClassType.MPVerb;
                type2 = MPClassType.MPNoun;
                label2.Text = "MP verb (Level 1)";
                label6.Text = "MP noun (Level 2)";
            }
            else
            {
                type1 = MPClassType.Noun;
                type2 = MPClassType.Noun;
                label2.Text = "Noun (Level 1)";
                label6.Text = "Noun (Level 2)";
            }

            model.VerbPart[1].type = type1;
            model.VerbPart[2].type = type2;
            foreach (MPClass c in model.VerbPart[1].list) c.type = type1;
            foreach (MPClass c in model.VerbPart[2].list) c.type = type2;




            switch (comboBox.Text)
            {
                case "1":
                    model.NounRel[0].type = "";
                    model.NounRel[1].type = "";
                    model.NounRel[2].type = "";
                    break;
                case "2":
                    model.NounRel[0].type = "";
                    model.NounRel[1].type = "";
                    model.NounRel[2].type = "";
                    break;
                case "2A":
                    model.NounRel[0].type = "assoc";
                    model.NounRel[1].type = "";
                    model.NounRel[2].type = "";
                    break;
                case "2B":
                    model.NounRel[0].type = "aggre";
                    model.NounRel[1].type = "";
                    model.NounRel[2].type = "";
                    break;
                case "2C":
                    model.NounRel[0].type = "prep";
                    model.NounRel[1].type = "";
                    model.NounRel[2].type = "";
                    break;
                case "3":
                    model.NounRel[0].type = "prep";
                    model.NounRel[1].type = "";
                    model.NounRel[2].type = "";
                    break;
                case "4":
                    model.NounRel[0].type = "prep";
                    model.NounRel[1].type = "assoc";
                    model.NounRel[2].type = "";
                    break;
                case "4A":
                    model.NounRel[0].type = "prep";
                    model.NounRel[1].type = "assoc";
                    model.NounRel[2].type = "prep";
                    break;
                case "4B":
                    model.NounRel[0].type = "prep";
                    model.NounRel[1].type = "aggre";
                    model.NounRel[2].type = "";
                    break;
                case "5":
                    model.NounRel[0].type = "assoc";
                    model.NounRel[1].type = "";
                    model.NounRel[2].type = "";
                    break;
                case "5A":
                    model.NounRel[0].type = "assoc";
                    model.NounRel[1].type = "prep";
                    model.NounRel[2].type = "";
                    break;
                case "6":
                    model.NounRel[0].type = "aggre";
                    model.NounRel[1].type = "";
                    model.NounRel[2].type = "";
                    break;
                case "7":
                    model.NounRel[0].type = "depend";
                    model.NounRel[1].type = "assoc";
                    model.NounRel[2].type = "";
                    break;
                case "8":
                    model.NounRel[0].type = "";
                    model.NounRel[1].type = "";
                    model.NounRel[2].type = "";
                    
                    model.VerbRel[0].type = "tran";

                    break;
                case "8A":
                    model.NounRel[0].type = "aggre";
                    model.NounRel[1].type = "";
                    model.NounRel[2].type = "";

                    model.VerbRel[0].type = "tran";
                    break;
                case "8B":
                    model.NounRel[0].type = "";
                    model.NounRel[1].type = "";
                    model.NounRel[2].type = "";

                    model.VerbRel[0].type = "tran";
                    break;
                case "8C":
                    model.NounRel[0].type = "aggre";
                    model.NounRel[1].type = "";
                    model.NounRel[2].type = "";

                    model.VerbRel[0].type = "tran";
                    break;
                case "8D":
                    model.NounRel[0].type = "";
                    model.NounRel[1].type = "";
                    model.NounRel[2].type = "";

                    model.VerbRel[0].type = "tran";
                    model.VerbRel[1].type = "assoc";
                    break;
                case "9":
                    model.NounRel[0].type = "aggre";
                    model.NounRel[1].type = "";
                    model.NounRel[2].type = "";
                    break;
                case "9A":
                    model.NounRel[0].type = "prep";
                    model.NounRel[1].type = "";
                    model.NounRel[2].type = "";
                    break;
                default:
                    break;
            }
            syncModel2Screen();

        }

        private void checkBox_CheckedChanged(object sender, EventArgs e)
        {
            model.existVerbModifier = checkBox.Checked;
            if (checkBox.Checked)
            {
                instruction2TextBox.Text = "Enter nouns in an MP verb modifier, and dependency relationship between nouns in an MP verb modifier and MP verbs except Type 8 (8A, 8B, 8C, and 8D).";
                model.VerbRel[0].type = "depend";
            }
            else
            {
                instruction2TextBox.Text = "";
                model.VerbRel[0].type = "";
            }
            syncModel2Screen();

        }
        private void updateInstructionText()
        {
            Dictionary<string, string> ins1 = new Dictionary<string, string>();
            ins1["1"] = "Enter MP nouns and MP verbs.";
            ins1["2"] = "Enter MP nouns, attributes, and MP verbs.";
            ins1["2A"] = "Enter MP nouns, attributes, nouns & attributes in an MP noun modifier, association relationships between MP nouns and nouns in an MP noun modifier, and MP verbs.";
            ins1["2B"] = "Enter MP nouns, attributes, nouns & attributes in an MP noun modifier, aggregation relationships between an MP noun and nouns in an MP noun modifier, and MP verbs";
            ins1["2C"] = "Enter MP nouns, attributes, nouns & attributes in an MP noun modifier, prepositional relationships between MP noun and nouns in an MP noun modifier, and MP verbs.";
            ins1["3"] = "Enter MP nouns, nouns in an MP noun modifier, prepositional relationships between MP nouns and nouns in an MP noun modifier, and MP verbs.";
            ins1["4"] = "Enter MP nouns, the 1st level nouns and the 2nd level nouns in an MP noun modifier, prepositional relationships between MP nouns and the 1st level nouns, association relationship between the 1st level nouns and 2nd level nouns, and MP verbs.";
            ins1["4A"] = "Enter MP nouns, the 1st (2nd and 3rd) level nouns in an MP noun modifier, prepositional relationships between MP nouns and the 1st level nouns, association relationships between the 1st level nouns and the 2nd level nouns, and prepositional relationships between the 2nd level nouns and 3rd level, and MP verbs.";
            ins1["4B"] = "Enter MP nouns, the 1st and 2nd level nouns in an MP noun modifier, prepositional relationships between MP nouns and the 1st level nouns, aggregation relationships between the 1st level nouns and the 2nd level nouns, and MP verbs.";
            ins1["5"] = "Enter MP nouns, nouns in an MP noun modifier, association relationships between MP nouns and nouns in an MP noun modifier, and MP verbs.";
            ins1["5A"] = "Enter MP nouns, the 1st and 2nd level nouns in an MP noun modifier,  association relationships between MP nouns and the 1st level nouns, prepositional relationships between the 1st level nouns and the 2nd level nouns, and MP verbs.";
            ins1["6"] = "Enter MP nouns, nouns in an MP noun modifier, aggregation relationships between MP nouns and nouns in an MP noun modifier, and MP verbs.";
            ins1["7"] = "Enter MP nouns, the 1st and 2nd level nouns in an MP noun modifier, dependency or association relationships between MP nouns and the 1st level nouns, association relationships between the 1st level nouns and the 2nd level nouns, and MP verbs.";
            ins1["8"] = "Enter MP nouns and MP verbs. Enter MP nouns and MP verbs in an MP verb modifier.  Enter transitive verb relationships between MP verbs and MP verbs in an MP verb modifier.";
            ins1["8A"] = "Enter MP nouns, nouns in an MP noun modifier, MP verbs, aggregation relationships between MP nouns and nouns in an MP noun modifier. Enter MP verbs, MP nouns in an MP verb modifier. Enter transitive verb relationships between MP verbs and MP verbs in an MP verb modifier.";
            ins1["8B"] = "Enter MP nouns and MP verbs. Enter nouns in an MP verb modifier and transitive verb relationships between MP verbs and nouns in an MP verb modifier.";
            ins1["8C"] = "Enter MP nouns, nouns in an MP noun modifier, aggregation relationships between MP nouns and nouns in an MP noun modifier, and MP verbs. Enter nouns in an MP verb modifier, and transitive verb relationships between MP verbs and nouns in an MP verb modifier.";
            ins1["8D"] = "Enter MP nouns, and MP verbs. Enter the 1st and 2nd level nouns in an MP verb modifier, transitive verb relationships between MP verbs and the 1st level nouns, association relationships between the 1st level nouns and the 2nd level nouns.";
            ins1["9"] = "Enter MP nouns and MP verbs. Enter MP nouns in an MP noun modifier and MP verbs in an MP noun modifier. Enter an aggregation relationship between MP nouns and MP nouns in an MP noun modifier.";
            ins1["9A"] = "Enter MP nouns and MP verbs. Enter MP nouns in an MP noun modifier and MP verbs in an MP noun modifier. Enter a prepostional relationship between MP noun and MP nouns in an MP noun modifier.";

            instruction1TextBox.Text = ins1[comboBox.Text];
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Are you sure?
            if (MessageBox.Show("Are you sure?", "New file", MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
                == DialogResult.Yes)
            {
                newModel();
                updateCurrentFilename("Noname");
                syncModel2Screen();
            }
        }

        private void updateCurrentFilename(string name)
        {
            currentFilename = name;
            this.Text = currentFilename + " - MPev " + MPevVersion;
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveAs();
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            textBox1.Text = textBox1.Text.Replace("\r\n", "");
            model.statement = textBox1.Text;
        }

        private void quickClearToolStripMenuItem_Click(object sender, EventArgs e)
        {
            newModel();
            updateCurrentFilename("Noname");
            syncModel2Screen();
        }

    }
}
